package cn.baiweigang.uu.service.calculate;

import cn.baiweigang.uu.db.dataobj.StockInfoDo;
import cn.baiweigang.uu.db.repository.HistoryDayInfoRepository;
import cn.baiweigang.uu.enums.ExtKeyEnum;
import cn.baiweigang.uu.utils.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.List;

@Service
@Slf4j
public class CalculateService {

    @Autowired
    private HistoryDayInfoRepository historyDayInfoRepository;

    public void calc(String ds) {
        List<StockInfoDo> stockInfoDoList = historyDayInfoRepository.queryByDs(ds);
        if (stockInfoDoList == null || stockInfoDoList.size() < 1) {
            log.info("当天无股票数据 不需要计算 ds=" + ds);
            return;
        }
        for (int i = 0; i < stockInfoDoList.size(); i++) {
            try{
                //计算每只票
                calc(stockInfoDoList.get(i));
            }catch (Throwable e){
                log.error(e.getMessage());
            }

        }
    }

    private void calc(StockInfoDo stockInfoDo) {
        //获取最近20天的日线数据
        List<StockInfoDo> last20 = historyDayInfoRepository.queryByDmBeforeDS(stockInfoDo.getDm(), stockInfoDo.getDs(), 20);
        //计算各个指标
        calcMa(stockInfoDo, last20);
        calcSum(stockInfoDo, last20);
        calcChange(stockInfoDo, last20);

        //保存到db
        historyDayInfoRepository.updateExt(stockInfoDo.getId(), stockInfoDo.getExt());
    }

    //计算变化
    private void calcChange(StockInfoDo stockInfoDo, List<StockInfoDo> last20) {
        ExtKeyEnum extKeyEnum = ExtKeyEnum.CHANGE1_PM;
        if (last20 == null || last20.size() < extKeyEnum.getSize()) {
            LogUtil.logInfo("历史数据不足  无法进行计算 " + extKeyEnum.getCode());
            return;
        }
        StockInfoDo today = last20.get(0);
        StockInfoDo yestoday = last20.get(1);
        //(昨天-今天)/今天 取整
        int change = (yestoday.getPm() - today.getPm()) / today.getPm();
        stockInfoDo.addExt(extKeyEnum.getCode(), change + "");
    }

    //求和
    private void calcSum(StockInfoDo stockInfoDo, List<StockInfoDo> last20) {
        calcSumByKey(stockInfoDo, last20, ExtKeyEnum.SUM3_ZD);
        calcSumByKey(stockInfoDo, last20, ExtKeyEnum.SUM5_ZD);
        calcSumByKey(stockInfoDo, last20, ExtKeyEnum.SUM20_ZD);
    }

    private void calcSumByKey(StockInfoDo stockInfoDo, List<StockInfoDo> stockInfoDoList, ExtKeyEnum extKeyEnum) {
        if (stockInfoDoList == null || stockInfoDoList.size() < extKeyEnum.getSize()) {
            return;
        }
        Double value = 0.00;
        for (int i = 0; i < extKeyEnum.getSize(); i++) {
            StockInfoDo tmp = stockInfoDoList.get(i);
            try {
                Field field = tmp.getClass().getDeclaredField(extKeyEnum.getFieldName());
                field.setAccessible(true);
                value += Double.parseDouble(field.get(tmp) + "");
            } catch (NoSuchFieldException | IllegalAccessException e) {
                log.error("对象属性不存在 或类型转换错误" + e.getMessage());
            }
        }
        stockInfoDo.addExt(extKeyEnum.getCode(), BigDecimal.valueOf(value).setScale(2, BigDecimal.ROUND_HALF_DOWN).toString());
    }

    //计算均值
    private void calcMa(StockInfoDo stockInfoDo, List<StockInfoDo> last20) {
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA5_C);
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA6_C);
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA10_C);
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA20_C);
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA5_E);
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA10_E);
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA20_E);
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA5_HS);
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA10_HS);
        calcMaByKey(stockInfoDo, last20, ExtKeyEnum.MA20_HS);
    }

    private void calcMaByKey(StockInfoDo stockInfoDo, List<StockInfoDo> stockInfoDoList, ExtKeyEnum extKeyEnum) {
        if (stockInfoDoList == null || stockInfoDoList.size() < extKeyEnum.getSize()) {
            return;
        }
        Double value = 0.00;
        for (int i = 0; i < extKeyEnum.getSize(); i++) {
            StockInfoDo tmp = stockInfoDoList.get(i);
            try {
                Field field = tmp.getClass().getDeclaredField(extKeyEnum.getFieldName());
                field.setAccessible(true);
                value += Double.parseDouble(field.get(tmp) + "");
            } catch (NoSuchFieldException | IllegalAccessException e) {
                log.error("对象属性不存在 或类型转换错误" + e.getMessage());
            }
        }
        Double ma = BigDecimal.valueOf(value / extKeyEnum.getSize()).setScale(2, BigDecimal.ROUND_HALF_DOWN).doubleValue();
        stockInfoDo.addExt(extKeyEnum.getCode(), ma + "");
    }
}
